#pragma once
#ifndef USES_H
#define USES_H
#include <vector>
#include <cassert>
#include <iosfwd>
#include <iterator>
#include <algorithm>
#include "Parent.h"
#include "ProcTable.h"
#include "spa_types.h"

#include <boost/dynamic_bitset.hpp>
#include <boost/unordered_map.hpp>

using namespace boost;
/*
typedef struct uses_entry {
		VARINDEX var_index;
		dynamic_bitset<> uses_bitset;
		PROCINDEX proc_index;
	} USESENTRY;
	*/
class Uses
{
private:
	bool debug;
	friend class UsesTest;

	boost::unordered_map<VARINDEX, STMT_ARRAY> var_stmts;
	boost::unordered_map<VARINDEX, PROCINDEX_ARRAY> var_procs;
	boost::unordered_map<PROCINDEX, VARINDEX_ARRAY> proc_vars;
	boost::unordered_map<unsigned int, VARINDEX_ARRAY> stmt_vars;
	
	STMT_ARRAY BitsetToStatementArray(boost::dynamic_bitset<> uses_bitset, NODETYPE node_type);
	STMT_ARRAY IdentifyParents(STMT_ARRAY children, STMT_ARRAY, NODETYPE,  int);
	void InitializeUses(int num_of_statements);
	int num_of_statements; 
	//vector<USESENTRY> uses_list; 
	
	Parent parent_test; 
	ProcTable proc_test; 
public:
		
	Uses(void);
	~Uses(void);
	void InsertUses(STMT, VARINDEX, PROCINDEX);
	VARINDEX_ARRAY GetVariablesUsedByAssignment(STMT);
	STMT_ARRAY GetAssignmentUsesVariable(VARINDEX);
	STMT_ARRAY GetContainerUsesVariable(VARINDEX, NODETYPE);
	VARINDEX_ARRAY GetVariablesUsedByContainer(STMT);
	PROCINDEX_ARRAY GetProcedureUsesVariable(VARINDEX);
	VARINDEX_ARRAY GetVariablesUsedByProcedure(PROCINDEX);
	BOOLEAN GetAssignmentUses(STMT,VARINDEX);
	
	// newly added
	BOOLEAN GetContainerUses(STMT, VARINDEX, NODETYPE);
	BOOLEAN GetStatementUses(STMT, VARINDEX);
	BOOLEAN GetProcedureUses(PROCINDEX, VARINDEX);

};

#endif